package com.xjh.basestudy.designmode.behaviorMode.behaviorMode9_Visitor.p1_origin;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

/**
 * @Author XuJianHua
 * @Date 2022/10/5 21:25
 * @Description
 * 输出结果显示糖果价格成功按九折计价，显然访问者能够顺利识别传入的参数是糖果类商品，并成功派发了相应的糖果计价方法visit (Candy candy)。当然，重载方法责有所归，其他商品类也同样适用于这种自动派发机制。
 *

 *

 */
public class Client {

    public static void main(String[] args) {
        //小兔奶糖，生产日期：2019-10-1，原价：￥20.00
        Candy candy = new Candy("小兔奶糖", LocalDate.of(2019, 10, 1), 20.00f);
        Visitor discountVisitor = new DiscountVisitor(LocalDate.of(2020, 1, 1));
        discountVisitor.visit(candy);
      /*输出：
         结算日期：2020-01-01
         =====糖果【小兔奶糖】打折后价格=====
         ￥18.00
       */

       /** * 至此，我们已经利用访问者的重载方法实现了计价方法的自动派发机制，难道这就是访问者模式吗？其实并非如此简单。通常顾客去超市购物不会只购买一件商品，
        * 尤其是当超市举办更大力度的商品优惠活动时，如图22-3所示，顾客们会将打折的商品一并加入购物车，结账时一起计价。如图22-3所示，针对这种特殊时期的计价方法也不难，
        * 只需要另外实现一个“优惠活动计价访问者类”就可以了。值得深思的是，访问者的重载方法只能对单个“具体”商品类进行计价，当顾客推着装有多件商品的购物车来结账时，“含糊不清”的“泛型”商品可能会引起重载方法的派发问题。
        * 实践出真知，我们用之前的访问者来做一个清空购物车的实验，请参看代码清单22-8。
        *
        *
        * ，顾客首先在第5行将3件商品加入了用List<Product>模拟的购物车中，其商品类泛型<Product>并没有声明确切的商品类别。接着，访问者在第13行迭代购物车中的每件商品并进行轮流计价，
        * 不幸的是，foreach循环只能用抽象商品类Product进行承接，可以看到此时在第14行引发的编译错误。
        * 重载方法自动派发不能再正常工作了，这是由于编译器对泛型化的商品类Product茫然无措，分不清到底是糖果还是酒，所以也就无法确定应该调用哪个重载方法了。
        *
        * 既然无法使用购物车将商品“混为一谈”（泛型化），那么需要顾客手动将同类商品分拣在一起，分别用3个购物车（如List<Candy>、List<Wine>和List<Fruit>）去收银处结算吗？这太麻烦了，无法实现。
        * 因此，如何解决访问者对泛型化的商品类的自动识别、分拣是当下最关键的问题。
        * */
                // 将3件商品加入购物车
                List<Product> products = Arrays.asList(
                        new Candy("小兔奶糖", LocalDate.of(2018, 10, 1), 20.00f),
                        new Wine("老猫白酒", LocalDate.of(2017, 1, 1), 1000.00f),
                        new Fruit("草莓", LocalDate.of(2018, 12, 26), 10.00f, 2.5f)
                );

                Visitor discountVisitor1 = new DiscountVisitor(LocalDate.of(2018, 1, 1));
                // 迭代购物车中的商品
                for (Product product : products) {
//                    discountVisitor.visit(product);// 此处会报错
                }



    }
}